package pl.edu.agh.ssm.monitor;

import java.net.InetAddress;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import pl.edu.agh.ssm.monitor.data.SessionConnection;
import pl.edu.agh.ssm.monitor.data.SessionNode;
import pl.edu.agh.ssm.monitor.data.Session;
import pl.edu.agh.ssm.monitor.data.SessionPair;
import pl.edu.agh.ssm.monitor.data.SessionType;

/**
 * Container for keep informations about multimedia sessions.
 * It allows to add, remove and find session.
 * @author Tomasz Jadczyk
 *
 */
public class SessionContainer {

	private HashMap<SessionPair, Session> sessions;
//	private HashMap<InetAddress, HashMap<Integer, Session>> sessions;
//
	public SessionContainer() {
		sessions = new HashMap<SessionPair, Session>();
//		sessions = new HashMap<InetAddress, HashMap<Integer, Session>>();
	}
//
	public void addSession(Session session, SessionPair pair) {
		sessions.put(pair, session);
	}
	
	public List<Session> getSessions(SessionType type) {
		LinkedList<Session> matchSession = new LinkedList<Session>();
		for(Session s : sessions.values()) {
			if(s.getSessionType() == type) {
				matchSession.add(s);
			}
		}
		return matchSession;
	}
	
	public List<Session> getSessions(InetAddress address) {
		LinkedList<Session> matchSession = new LinkedList<Session>();
		for(SessionPair pair : sessions.keySet()) {
			if(pair.getAddress() == address) {
				matchSession.add(sessions.get(pair));
			}
		}
		return matchSession;
	}
	
	public List<Session> getSessions(int port) {
		LinkedList<Session> matchSession = new LinkedList<Session>();
		for(SessionPair pair : sessions.keySet()) {
			if(pair.getPort() == port) {
				matchSession.add(sessions.get(pair));
			}
		}
		return matchSession;
	}
	
	public Session getSession(SessionPair pair) {
		return sessions.get(pair);
	}
//	public Session getSession(InetAddress address, int port) {
//		// SessionPair key = new SessionPair(address, port);
//		// Session session = sessions.get(key);
//		HashMap<Integer, Session> sessionsAddr = sessions.get(address);
//		if (sessionsAddr == null) {
//			// session = new Session(System.currentTimeMillis());
//			// session.setSessionDesc(address.getHostAddress() + "/" +
//			// Integer.toString(port));
//			// sessions.put(key, session);
//			sessionsAddr = new HashMap<Integer, Session>();
//			sessions.put(address, sessionsAddr);
//		}
//		Session session = sessionsAddr.get(Integer.valueOf(port));
//		if (session == null) {
//			session = new Session(System.currentTimeMillis());
//			session.setSessionDesc(address.getHostAddress() + "/"
//					+ Integer.toString(port));
//			sessionsAddr.put(Integer.valueOf(port), session);
//		}
//
//		printAll();
//		return session;
//	}
//
//	public List<Session> getAllSessions() {
//		return null;
//	}
//
//	public List<Session> getSessions(SessionType type) {
//		return null;
//	}
//
//	public SessionNode addParticipant(InetAddress ip, Session session, long ssrc) {
//		//Node node = new Node(ip);
//		SessionNode node = null;
//		for(SessionNode n : session.getSessionParticipants()) {
//			if(n.getAddress().equals(ip)) {
//				node = n;
//				break;
//			}
//		}
//		if(node == null) {
//			node = new SessionNode(ip);
//			node.setSsrc(ssrc);
//			session.addNode(node);
//		}
//
//		if(ssrc != node.getSsrc()) {
//			//ssrc changed (maybe conflict)
//			node.setSsrc(ssrc); 
//		}
//		
//		printAll();
//		return node;
//
//	}
//	
//	public void removeParticipant(InetAddress ip, Session session) {
//		
//	}

	public void printAll() {
		System.out.println("Print:");
//		for (HashMap<Integer, Session> portSession : sessions.values()) {
			for (Session s : sessions.values()) {
				System.out.println(s.getSessionDesc());
				for (SessionNode n : s.getSessionParticipants()) {
					System.out.println("\t" + n.getAddress().getHostAddress() +
							" " + n.getNodeType() + ": " + n.getSsrc());
					List<SessionConnection> sourceConnections = s.getConnectionsFromSource(n);
					for(SessionConnection cn : sourceConnections) {
						System.out.println("\t\t\tConnected to : " + 
								cn.getReceiver().getAddress().getHostAddress() + 
								" ssrc:" + cn.getReceiver().getSsrc());
					}
				}
			}
//		}
	}

	public void removeSession(Session session) {
		LinkedList<SessionPair> pairs = new LinkedList<SessionPair>();
		for(SessionPair sp : sessions.keySet()) {
			if(sessions.get(sp) == session) {
				pairs.add(sp);
			}
		}
		for(SessionPair sp : pairs) {
			sessions.remove(sp);
		}
	}
	
	public void removeSession(SessionPair pair) {
		sessions.remove(pair);
	}
}
